﻿using DevExpress.Data.Utils;
using HalconDotNet;
using ImageDefine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ImageToolCircle
{
    public class ImageActionerCircle
    {
        public ImageToolCircle imageTool;

        public ImageActionerCircle()
        {
            
        }
        public ImageActionerCircle(ImageToolCircle toolBase)
        {
            imageTool = toolBase;

        }

        public bool Run(HalconDotNet.HImage imageInput, SmartDisplayControl.SmartDisplayControl disPlayControl)
        {
            bool bResult = false;
            GeneralLib.HiPerfTimer timer = new GeneralLib.HiPerfTimer();
            timer.Start();

            try
            {

                if (imageTool.strTraceName == "")
                {
                    RunToool(imageInput, disPlayControl);

                }
                else
                {
                    try
                    {
                        ImageToolBase toolTrace = imageTool.imageTask.dicTools[imageTool.strTraceName];

                        imageTool.ImageToolResults = new List<ImageToolResult>();
                        imageTool.OutPutResults.Clear();
                        if (toolTrace.ImageToolResults.Count > 0)
                        {
                            for (int i = 0; i < toolTrace.ImageToolResults.Count; i++)
                            {
                                RunToool(imageInput, disPlayControl, i);
                            }
                            ImageResultCircle imageResultCircle = imageTool.ImageToolResults[0] as ImageResultCircle;
                            imageTool.ResultX = imageResultCircle.ResultX;
                            imageTool.ResultY = imageResultCircle.ResultY;
                            imageTool.dRadius = imageResultCircle.CircleR;
                            imageTool.bResultOK = imageResultCircle.Result;
                        }
                        else
                        {
                            imageTool.ResultX = 0.0;
                            imageTool.ResultY = 0.0;
                            imageTool.dRadius = 0.0;
                            imageTool.bResultOK = false;
                        }
                    }
                    catch
                    {

                    }
                }
            }
            catch//(Exception ex)
            {
                bResult = false;
                imageTool.bResultOK = false;
            }

            imageTool.dTimeUsed = timer.Duration;
            return bResult;
        }

        public bool RunToool(HImage image, SmartDisplayControl.SmartDisplayControl disWnd)
        {

            imageTool.OutPutResults.Clear(); ;
            imageTool.ResultX = 0.0;
            imageTool.ResultY = 0.0;
            imageTool.ResultA = 0.0;
            imageTool.ResultOK = false;
            imageTool.dResultScore = 0.0;
            imageTool.ImageToolResults = new List<ImageToolResult>();
            ImageResultCircle imageResultCirlce = new ImageResultCircle();
            if (image == null || disWnd == null)
            {
                return false;
            }
            #region regtionSetting
            HRegion regionR = new HRegion();
            HRegion regionT;
            double AngleOfTrace = 0.0;
            regionR.GenCircle(imageTool.Setting.RowCenter, imageTool.Setting.ColumnCenter, imageTool.Setting.Radius);
            if (imageTool.strTraceName == "")
            {
                regionT = regionR;
                AngleOfTrace = 0.0;
            }
            else
            {
                try
                {
                    //ImageDefine.ImageToolBase toolTrace = ImageTask.ImageTaskManager.taskCenter.dicTasks[strTaskName].dicTools[actionerSettingSelf.strTraceName];

                    ImageDefine.ImageToolBase toolTrace;

                    toolTrace = imageTool.imageTask.dicTools[imageTool.strTraceName];

                    if (toolTrace is ImageDefine.IAffine)
                    {
                        ImageDefine.IAffine regionAffine = (ImageDefine.IAffine)toolTrace;
                        regionT = regionAffine.TransRegion(regionR);
                        AngleOfTrace = toolTrace.dResultA;
                    }
                    else
                    {
                        regionT = regionR;
                        AngleOfTrace = 0.0;
                    }
                }
                catch
                {
                    regionT = regionR;
                    AngleOfTrace = 0.0;
                }
            }

            #endregion


            #region 运行过程
            double dRowTran, dColTran, dRadiusTran;
            regionT.SmallestCircle(out dRowTran, out dColTran, out dRadiusTran);

            HMetrologyModel metrologyObject = new HMetrologyModel();
            metrologyObject.CreateMetrologyModel();
            int iWidth, iHeight;
            image.GetImageSize(out iWidth, out iHeight);
            metrologyObject.SetMetrologyModelImageSize(iWidth, iHeight);
            HTuple iToolIndex;
            string strPointOrder = "positive";
            if (imageTool.Setting.PointOrderCW)
            {
                strPointOrder = "negative";
            }
            if (imageTool.Setting.MeasureNums == 0)
            {
                iToolIndex = metrologyObject.AddMetrologyObjectCircleMeasure(new HTuple(dRowTran), new HTuple(dColTran), new HTuple(dRadiusTran), new HTuple(imageTool.Setting.Length1), new HTuple(imageTool.Setting.Length2),
               new HTuple(imageTool.Setting.Sigma), new HTuple(imageTool.Setting.Threshold), new HTuple(), new HTuple());

            }
            else
            {
                iToolIndex = metrologyObject.AddMetrologyObjectCircleMeasure(new HTuple(dRowTran), new HTuple(dColTran), new HTuple(dRadiusTran), new HTuple(imageTool.Setting.Length1), new HTuple(imageTool.Setting.Length2),
               new HTuple(imageTool.Setting.Sigma), new HTuple(imageTool.Setting.Threshold), new HTuple(new string[] { "num_measures", "start_phi", "end_phi", "point_order" }),
               new HTuple(new object[] { imageTool.Setting.MeasureNums, AngleToHu(imageTool.Setting.StartAngle), AngleToHu(imageTool.Setting.EndAngle), strPointOrder }));
            }

            if (imageTool.Setting.MeasureDir == MeasureDir.BlackToWhite)
            {
                metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("measure_transition"), new HTuple("positive"));
            }
            else
            {
                metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("measure_transition"), new HTuple("negative"));
            }

            metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("measure_select"), new HTuple(imageTool.Setting.MeasureSelect.ToString()));

            //metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("start_phi"), new HTuple(AngleToHu(actionerSettingSelf.CircleSetting.StartAngle)));
            //metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("end_phi"), new HTuple(AngleToHu(actionerSettingSelf.CircleSetting.EndAngle)));

            HTuple hTupleParameter = metrologyObject.GetMetrologyObjectParam(iToolIndex, new HTuple("min_score"));
            metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("min_score"), new HTuple(imageTool.Setting.MinScore));
            metrologyObject.ApplyMetrologyModel(image);




            #endregion

            #region 结果赋值
            HTuple hResult = metrologyObject.GetMetrologyObjectResult(iToolIndex, new HTuple("all"), new HTuple("result_type"), new HTuple("all_param"));

            HXLDCont countResult = metrologyObject.GetMetrologyObjectResultContour(new HTuple("all"), new HTuple("all"), new HTuple(1.5));
            HTuple hMeasureRows, hMeasureCols;
            HXLDCont countMeasure = metrologyObject.GetMetrologyObjectMeasures(new HTuple("all"), new HTuple("all"), out hMeasureRows, out hMeasureCols);
            HXLDCont countCross = new HXLDCont();
            countCross.GenCrossContourXld(hMeasureRows, hMeasureCols, new HTuple(6), new HTuple(0));

            if (imageTool.Setting.ShowMeasureWnd)
                disWnd.DispObj(countMeasure, "gray");
            if (imageTool.Setting.ShowMeasurePt)
                disWnd.DispObj(countCross, "cyan");
            if (imageTool.Setting.ShowMeasureResultLine)
            {
                disWnd.DispObj(countResult, "green");
            }



            if (hResult.Length > 0)
            {
                imageTool.ResultX = hResult[1];
                imageTool.ResultY = hResult[0];
                imageTool.dRadius = hResult[2];
                


                if (imageTool.Setting.ShowCircle)
                {
                    disWnd.DispCircle(imageTool.ResultY, imageTool.ResultX,imageTool.dRadius,"green");
                    HalconDotNet.HXLDCont crossXLD1 = new HalconDotNet.HXLDCont();
                    crossXLD1.GenCrossContourXld(imageTool.ResultY, imageTool.ResultX, 40, 0.0);
                    disWnd.DispObj(crossXLD1,"green");
                }
                imageTool.OutPutResults.Add("Raduis", imageTool.dRadius.ToString("0.0000"));


                imageTool.dResultScore = 0.0;
                imageTool.dResultA = 0;
              
                imageTool.bResultOK = true;

                imageResultCirlce.ResultX = imageTool.ResultX;
                imageResultCirlce.ResultY = imageTool.ResultY;
                imageResultCirlce.ResultA = imageTool.ResultA;
                imageResultCirlce.ResultScore = imageTool.dResultScore;
                imageResultCirlce.CircleR = imageTool.dRadius;
                imageResultCirlce.Result = true;
                imageTool.ImageToolResults.Add(imageResultCirlce);
            }
            else
            {
                imageTool.ResultX = 0.0;
                imageTool.ResultY = 0.0;
                imageTool.dRadius = 0.0;
                imageTool.dResultScore = 0.0;
                imageTool.dResultA = 0;
                imageTool.bResultOK = false;

                imageResultCirlce.ResultX = imageTool.ResultX;
                imageResultCirlce.ResultY = imageTool.ResultY;
                imageResultCirlce.ResultA = imageTool.ResultA;
                imageResultCirlce.ResultScore = imageTool.dResultScore;
                imageResultCirlce.CircleR = imageTool.dRadius;
                imageResultCirlce.Result = false;
                imageTool.ImageToolResults.Add(imageResultCirlce);
                return false;
            }
            #endregion
            return true;

        }
        public bool RunToool(HImage image, SmartDisplayControl.SmartDisplayControl disWnd, int iIndex)
        {

            imageTool.ResultX = 0.0;
            imageTool.ResultY = 0.0;
            imageTool.ResultA = 0.0;
            imageTool.ResultOK = false;
            imageTool.dResultScore = 0.0;
            ImageResultCircle imageResultCirlce = new ImageResultCircle();
            if (image == null || disWnd == null)
            {
                return false;
            }
            #region regtionSetting
            HRegion regionR = new HRegion();
            HRegion regionT;
            double AngleOfTrace = 0.0;
            regionR.GenCircle(imageTool.Setting.RowCenter, imageTool.Setting.ColumnCenter, imageTool.Setting.Radius);
            if (imageTool.strTraceName == "")
            {
                regionT = regionR;
                AngleOfTrace = 0.0;
            }
            else
            {
                try
                {
                    //ImageDefine.ImageToolBase toolTrace = ImageTask.ImageTaskManager.taskCenter.dicTasks[strTaskName].dicTools[actionerSettingSelf.strTraceName];

                    ImageDefine.ImageToolBase toolTrace;

                    toolTrace = imageTool.imageTask.dicTools[imageTool.strTraceName];

                    if (toolTrace is ImageDefine.IAffine)
                    {
                        ImageDefine.IAffine regionAffine = (ImageDefine.IAffine)toolTrace;
                        regionT = regionAffine.TransRegion(regionR,iIndex);
                        AngleOfTrace = toolTrace.dResultA;
                    }
                    else
                    {
                        regionT = regionR;
                        AngleOfTrace = 0.0;
                    }
                }
                catch
                {
                    regionT = regionR;
                    AngleOfTrace = 0.0;
                }
            }

            #endregion


            #region 运行过程
            double dRowTran, dColTran, dRadiusTran;
            regionT.SmallestCircle(out dRowTran, out dColTran, out dRadiusTran);

            HMetrologyModel metrologyObject = new HMetrologyModel();
            metrologyObject.CreateMetrologyModel();
            int iWidth, iHeight;
            image.GetImageSize(out iWidth, out iHeight);
            metrologyObject.SetMetrologyModelImageSize(iWidth, iHeight);
            HTuple iToolIndex;
            string strPointOrder = "positive";
            if (imageTool.Setting.PointOrderCW)
            {
                strPointOrder = "negative";
            }
            if (imageTool.Setting.MeasureNums == 0)
            {
                iToolIndex = metrologyObject.AddMetrologyObjectCircleMeasure(new HTuple(dRowTran), new HTuple(dColTran), new HTuple(dRadiusTran), new HTuple(imageTool.Setting.Length1), new HTuple(imageTool.Setting.Length2),
               new HTuple(imageTool.Setting.Sigma), new HTuple(imageTool.Setting.Threshold), new HTuple(), new HTuple());

            }
            else
            {
                iToolIndex = metrologyObject.AddMetrologyObjectCircleMeasure(new HTuple(dRowTran), new HTuple(dColTran), new HTuple(dRadiusTran), new HTuple(imageTool.Setting.Length1), new HTuple(imageTool.Setting.Length2),
               new HTuple(imageTool.Setting.Sigma), new HTuple(imageTool.Setting.Threshold), new HTuple(new string[] { "num_measures", "start_phi", "end_phi", "point_order" }),
               new HTuple(new object[] { imageTool.Setting.MeasureNums, AngleToHu(imageTool.Setting.StartAngle), AngleToHu(imageTool.Setting.EndAngle), strPointOrder }));
            }

            if (imageTool.Setting.MeasureDir == MeasureDir.BlackToWhite)
            {
                metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("measure_transition"), new HTuple("positive"));
            }
            else
            {
                metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("measure_transition"), new HTuple("negative"));
            }

            metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("measure_select"), new HTuple(imageTool.Setting.MeasureSelect.ToString()));

            //metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("start_phi"), new HTuple(AngleToHu(actionerSettingSelf.CircleSetting.StartAngle)));
            //metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("end_phi"), new HTuple(AngleToHu(actionerSettingSelf.CircleSetting.EndAngle)));

            HTuple hTupleParameter = metrologyObject.GetMetrologyObjectParam(iToolIndex, new HTuple("min_score"));
            metrologyObject.SetMetrologyObjectParam(iToolIndex, new HTuple("min_score"), new HTuple(imageTool.Setting.MinScore));
            metrologyObject.ApplyMetrologyModel(image);




            #endregion

            #region 结果赋值
            HTuple hResult = metrologyObject.GetMetrologyObjectResult(iToolIndex, new HTuple("all"), new HTuple("result_type"), new HTuple("all_param"));

            HXLDCont countResult = metrologyObject.GetMetrologyObjectResultContour(new HTuple("all"), new HTuple("all"), new HTuple(1.5));
            HTuple hMeasureRows, hMeasureCols;
            HXLDCont countMeasure = metrologyObject.GetMetrologyObjectMeasures(new HTuple("all"), new HTuple("all"), out hMeasureRows, out hMeasureCols);
            HXLDCont countCross = new HXLDCont();
            countCross.GenCrossContourXld(hMeasureRows, hMeasureCols, new HTuple(6), new HTuple(0));

           

            if (imageTool.Setting.ShowMeasureWnd)
                disWnd.DispObj(countMeasure, "gray");
            if (imageTool.Setting.ShowMeasurePt)
                disWnd.DispObj(countCross, "cyan");
            if (imageTool.Setting.ShowMeasureResultLine)
            {
                disWnd.DispObj(countResult, "green");
            }



            if (hResult.Length > 0)
            {
                imageTool.ResultX = hResult[1];
                imageTool.ResultY = hResult[0];
                imageTool.dRadius = hResult[2];



                if (imageTool.Setting.ShowCircle)
                {
                    disWnd.DispCircle(imageTool.ResultY, imageTool.ResultX, imageTool.dRadius, "green");
                    HXLDCont countCross1 = new HXLDCont();
                    countCross1.GenCrossContourXld(imageTool.ResultY, imageTool.ResultX, 60, 0);
                    disWnd.DispObj(countCross1, "green");
                }
                imageTool.OutPutResults.Add("Raduis"+iIndex.ToString(), imageTool.dRadius.ToString("0.0000"));


                imageTool.dResultScore = 0.0;
                imageTool.dResultA = 0;

                imageTool.bResultOK = true;

                imageResultCirlce.ResultX = imageTool.ResultX;
                imageResultCirlce.ResultY = imageTool.ResultY;
                imageResultCirlce.ResultA = imageTool.ResultA;
                imageResultCirlce.ResultScore = imageTool.dResultScore;
                imageResultCirlce.CircleR = imageTool.dRadius;
                imageResultCirlce.Result = true;
                imageTool.ImageToolResults.Add(imageResultCirlce);
            }
            else
            {
                imageTool.ResultX = 0.0;
                imageTool.ResultY = 0.0;
                imageTool.dRadius = 0.0;
                imageTool.dResultScore = 0.0;
                imageTool.dResultA = 0;
                imageTool.bResultOK = false;

                imageResultCirlce.ResultX = imageTool.ResultX;
                imageResultCirlce.ResultY = imageTool.ResultY;
                imageResultCirlce.ResultA = imageTool.ResultA;
                imageResultCirlce.ResultScore = imageTool.dResultScore;
                imageResultCirlce.CircleR = imageTool.dRadius;
                imageResultCirlce.Result = false;
                imageTool.ImageToolResults.Add(imageResultCirlce);
                return false;
            }
            #endregion
            return true;

        }
        private double HuToAngle(double dHu)
        {
            return dHu / Math.PI * 180.0;
        }
        private double AngleToHu(double dAngle)
        {
            return dAngle / 180.0 * Math.PI;
        }
    }
}
